home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 3402 < prev    next >
Encoding:
Text File  |  1996-08-06  |  4.1 KB  |  96 lines

  1. Path: newsbf02.news.aol.com!not-for-mail
  2. From: frankeye@aol.com (FrankEye)
  3. Newsgroups: comp.lang.c++
  4. Subject: Composition Insights Please!
  5. Date: 23 Jan 1996 14:37:35 -0500
  6. Organization: America Online, Inc. (1-800-827-6364)
  7. Sender: root@newsbf02.news.aol.com
  8. Message-ID: <4e3ddv$nnp@newsbf02.news.aol.com>
  9. Reply-To: frankeye@aol.com (FrankEye)
  10. NNTP-Posting-Host: newsbf02.mail.aol.com
  11.  
  12.  
  13. Can anybody share any insightful guidelines regarding the employment of
  14. class composition (a.k.a. "aggregation")  in C++?  I know the difference
  15. between it and inheritance.  I was surprised by the lack of mention or at
  16. most the mere acknowledgement of composition in the C++ FAQ (both online &
  17. book), Lippman's Primer, ARM, and Designing & Coding Reusable C++
  18. (Carroll&Ellis).  
  19.  
  20. +++++++++++++
  21.  
  22. One guideline I've come across is the "Law of Demeter", which asserts that
  23. the methods of a composite (aggregate) class should only be aware of the
  24. members of its immediate component classes, and not attempt to talk to the
  25. once-removed interfaces of its components' components.  For example,
  26. consider the manipulation of a hierarchical geometry model within a
  27. CAD/Visualization program:
  28.  
  29.   /*  Below conforms to Law of Demeter */
  30.  class Vehicle  {
  31.     composed of Parts (implemented as a List of class Part)
  32.   void setPitchAngle(double& pitch) {parts -> setPitchAngle(pitch)}
  33.   }
  34.  class Part {
  35.      composed of Patches (implemented as a List of class Patch)
  36.    void setPitchAngle(double& pitch) {patches -> setPitchAngle(pitch)}
  37.   }
  38.  class Patch  {
  39.      composed of Facets (implemented as a List of class Facet)
  40.    void setPitchAngle(double& pitch) {facets -> setPitchAngle(pitch)}
  41.   }
  42.  class Facet  {
  43.      composed of Ordered Vertices
  44.    void setPitchAngle(double& pitch) { // rotates vertex coordinates  }
  45.   }
  46.  
  47. The above example illustrates the proliferation of "traversal code" which
  48. is the gluecode necessary for the design of aggregate (composite) classes
  49. to comply with the Law of Demeter.  For aggregate classes, traversal code
  50. is comprised of those member functions at the aggregate class level which
  51. access or manipulate the state of the component member classes.  Notice
  52. that at each level in this example, one may identify an aggregate class. 
  53. Such nested aggregation, which may be desired in order to isomorphically
  54. model the problem domain, is also the cause of many redundant small
  55. methods (e.g., setPitchAngle()) which exist merely to "propagate" a method
  56. down to the component class elements which actually "do the work" or are
  57. worked upon.  
  58.  
  59. Why not merely implement setPitchAngle() as a singular function within the
  60. Vehicle class and eliminate the intermediate traversal code?, e.g.:
  61.  
  62.   /* Violates Law of Demeter */
  63.  void Vehicle::setPitchAngle(double& pitch)  {  
  64.    for all parts i:  
  65.       for all patches j of part[i]:  
  66.           for all facets k of patch[j]:  
  67.               part[i].patch[j].facet[k].setPitchAngle(pitch);
  68.   }
  69.  
  70. The answer supporting the Law of Demeter, I suppose, is that such code is
  71. brittle in the face of modifications to the class composition hierarchy,
  72. e.g., if we later decided that a Part->composed of->Assemblys->composed
  73. of->Patchs instead of Part->composed of->Patchs.  Depending on the depth
  74. of the composition nesting, it may in general be more expensive to fix
  75. code such as the above, rather than fix/insert traversal code only at the
  76. broken boundaries of the composition graph.  
  77.  
  78. In fact, I was made aware of the Law of Demeter by a student of Prof. Karl
  79. Lieberherr of Northeastern Univ., who has presided over the creation of
  80. the "adaptive software" method captured in his Demeter/C++ Tools set. 
  81. This "Demeter method" eliminates the manual generation and maintenance
  82. (resulting from changes, enhancements to class composition graph) of
  83. traversal code, by making use of graph traversal methods from aggregate
  84. class nodes (e.g., Vehicle) via any encountered component classes to
  85. destination class nodes (e.g., Facet).   
  86.  
  87. ++++++++++
  88.  
  89. Has anybody out there benefitted by conforming to the Law of Demeter?  Are
  90. there any other design issues regarding composition?   
  91.  
  92.  
  93.  
  94. Frank J. Iannarilli, Jr.
  95. frankeye@aol.com  OR franki@aerodyne.com
  96.